﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ArtemisTest
{
    /// <summary>
    /// Stores and Returns created components with various methods.
    /// </summary>
    public class ComponentFactory
    {
        Dictionary<ComponentType, Dictionary<long, Component>> _fromTypeExtended;
        Dictionary<long, Dictionary<ComponentType, Component>> _fromIndex;
        Dictionary<string, Dictionary<ComponentType, Dictionary<long,Component>>> _fromTag;

        /// <summary>Adds a new component to game. Stores into 3 different dictionaries</summary>
        public void AddComponent(Component c, long uid)
        {
            if (!_fromIndex.ContainsKey(uid))
            {
                _fromIndex.Add(uid, new Dictionary<ComponentType, Component>());
            }
            _fromIndex[uid].Add(c.Type, c);

            if (!_fromTypeExtended.ContainsKey(c.Type))
            {
                _fromTypeExtended.Add(c.Type, new Dictionary<long, Component>());
            }
            _fromTypeExtended[c.Type].Add(uid, c);

            foreach(string tag in c.Tags)
            {
                if (!_fromTag.ContainsKey(tag))
                {
                    _fromTag.Add(tag,new Dictionary<ComponentType,Dictionary<long,Component>>());
                    if (!_fromTag[tag].ContainsKey(c.Type))
                    {
                        _fromTag[tag].Add(c.Type, new Dictionary<long, Component>());
                    }
                }
                _fromTag[tag][c.Type].Add(uid, c);
                //_fromTag[tag].Add(c.Type, c);
            }
        }

        /// <summary>Removes a component from all dictionaries </summary>
        public void RemoveComponent(ComponentType c, long uid)
        {
            Component d = _fromIndex[uid][c];
            List<string> tags = d.Tags;

            foreach (string tag in tags)
            {
                _fromTag[tag][c].Remove(uid);
            }

            _fromTypeExtended[c].Remove(uid);
            _fromIndex[uid].Remove(c);
        }

        /// <summary>returns a component given the Component Type and unique id</summary>
        public Component GetComponent(ComponentType c, long uid)
        {
            if (_fromIndex.ContainsKey(uid))
            {
                if (_fromIndex[uid].ContainsKey(c))
                {
                    return _fromIndex[uid][c];
                }
            }
            return null;
        }

        /// <summary>returns a list of components that have a tag and are of type ct</summary>
        public Dictionary<long,Component> GetComponentsFromTag(string tag, ComponentType ct)
        {
            if (tag != null)
            {
                if (_fromTag.ContainsKey(tag))
                {
                    if (_fromTag[tag].ContainsKey(ct))
                    {
                        return _fromTag[tag][ct];
                    }
                }
                return null;
            }
            return null;
        }

        /// <summary>Returns a list of components of type ct</summary>
        public Dictionary<long, Component> GetAllComponentsOfType(ComponentType ct)
        {
            if (!_fromTypeExtended.ContainsKey(ct)) { Misc.CountComponentNotFound(); return new Dictionary<long, Component>(); }
            return _fromTypeExtended[ct];
        }

        public ComponentFactory()
        {
            _fromIndex = new Dictionary<long, Dictionary<ComponentType, Component>>();
            _fromTypeExtended = new Dictionary<ComponentType, Dictionary<long, Component>>();
            _fromTag = new Dictionary<string, Dictionary<ComponentType, Dictionary<long, Component>>>();
        }
    }

    public class EntityFactory
    {
        long uidGenerator = 0;

        public long GetNewEntity(int tid)
        {
            Console.WriteLine("entity given = " + (uidGenerator +1));
            uidGenerator = uidGenerator + 1;
            return uidGenerator;
        }

        //Clean this stuff up
        List<string[]> _sceneryTemplate;
        List<string[]> _sceneryPlacement;
        public void CreateScenery(int x, int y,int sceneryId, EntitySystem es)
        {
            long en =  GetNewEntity(-1);
            Position p = new Position(en, x, y);
            Img im = new Img(en, Convert.ToInt16(_sceneryTemplate[sceneryId][0]), System.Drawing.Color.White);
            Bounds b = new Bounds(en, 32, 32);
            es.Components.AddComponent(p, en);  //add position
            es.Components.AddComponent(im, en); //add image
            es.Components.AddComponent(b, en);  //add bounds
            es.AddEntity(en);
        }

        public EntityFactory()
        {
            _sceneryTemplate = ScriptReader.GetData("scenery\\template.txt");
            _sceneryPlacement = ScriptReader.GetData("scenery\\placement.txt");
        }
    }

}
